package cn.zhxu.toys.util;

import org.apache.commons.codec.binary.Hex;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class AesUtils {

	/**
	 * 加密模式.
	 */
	private static final String KEY_MODE = "AES";

	/**
	 * 密钥长度.
	 */
	private static final int KEY_LENGTH = 128;

	/**
	 * 加密令牌.
	 */
	private Cipher encryptCipher = null;

	/**
	 * 解密令牌.
	 */
	private Cipher decryptCipher = null;

	/**
	 * 指定密钥构造方法.
	 *
	 * @param strKey
	 *            指定的密钥
	 * @throws Exception
	 *             异常
	 */
	public AesUtils(final String strKey) throws Exception {
		KeyGenerator generator = KeyGenerator.getInstance(KEY_MODE);
		SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
		secureRandom.setSeed(strKey.getBytes());
		generator.init(KEY_LENGTH, secureRandom);
		SecretKey secretKey = generator.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();
		SecretKeySpec key = new SecretKeySpec(enCodeFormat, KEY_MODE);
		/**
		 * 默认使用 AES/ECB/PKCS5Padding
		 * 无偏移向量
		 */
		encryptCipher = Cipher.getInstance(KEY_MODE);
		encryptCipher.init(Cipher.ENCRYPT_MODE, key);

		decryptCipher = Cipher.getInstance(KEY_MODE);
		decryptCipher.init(Cipher.DECRYPT_MODE, key);
	}

	/**
	 * 加密字节数组.
	 *
	 * @param arr
	 *            需加密的字节数组
	 * @return 加密后的字节数组
	 * @throws Exception
	 *             异常
	 */
	public byte[] encrypt(final byte[] arr) throws Exception {
		return encryptCipher.doFinal(arr);
	}

	/**
	 * 加密字符串.
	 *
	 * @param strIn
	 *            需加密的字符串
	 * @return 加密后的字符串
	 * @throws Exception
	 *             异常
	 */
	public String encrypt(final String strIn) throws Exception {
		return StringUtils.toHexStr(encrypt(strIn.getBytes(StandardCharsets.UTF_8)));
	}

	/**
	 * 解密字节数组.
	 *
	 * @param arr
	 *            需解密的字节数组
	 * @return 解密后的字节数组
	 * @throws Exception
	 *             异常
	 */
	public byte[] decrypt(final byte[] arr) throws Exception {
		return decryptCipher.doFinal(arr);
	}

	/**
	 * 解密字符串.
	 *
	 * @param strIn
	 *            需解密的字符串
	 * @return 解密后的字符串
	 * @throws Exception
	 *             异常
	 */
	public String decrypt(final String strIn) throws Exception {
		return new String(decrypt(Hex.decodeHex(strIn.toCharArray())), StandardCharsets.UTF_8);
	}

	
	public static void main(String[] args) throws Exception {
		AesUtils aes = new AesUtils("123");
		String result = aes.encrypt("123456");
		System.out.println("result = " + result);
	}
	
}
